<?php


namespace App\Http\Controllers\Weapp;


use App\Jobs\OrderCancel;
use App\Model\AddressCopy;
use App\Model\GoodsSku;
use App\Model\OrderGoods;
use App\Model\OrderMention;
use App\Model\ReceiptCode;
use App\Model\StoreCopy;
use App\Tool\GetOrderPrice;
use App\Tool\Json;
use App\Tool\PayStatus;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;

class Order extends Auth
//class Order extends Base
{

    /**
     * 已扣库存（秒杀）
     * ['goods_sku_id'=>'20','num'=>10]
     * @var array
     */
    protected $stock=[];


    /**
     * 生成订单
     * Create by Peter
     * 2020/01/07 13:16:55
     * Email:904801074@qq.com
     * @param GetOrderPrice $getOrderPrice
     * @return false|string
     * @throws \Exception
     */
    function create_order(GetOrderPrice $getOrderPrice)
    {



        try {

            \DB::beginTransaction();

            //获取用户id
            $user_id = resolve('weapp_user')['id'];

            //获取商品id和商品数量 15*1!16*2  解释为id15(skuid)的商品1个和id16(skuid)的商品2个
            $param = request()->input('param');

            $array = explode('!', $param);

            $goods_info = [];

            foreach ($array as $key => $value) {


                $array_detail = explode('*', $value);
                //skuid
                $sku_id = $array_detail[0];
                //商品数量
                $num = $array_detail[1];

                $goods_data = GoodsSku::with('goods')->with('snapped_sku.snapped')
                    ->with('goods_sku_detail')->find($sku_id);


                //减库存
                $this->changeGoodsNum($sku_id, $num,$goods_data);

                //清除购物车中商品
                $this->changeShopCarNum($sku_id);


                //写入购买数量（goods_data中的num为库存数量）
                $goods_data['buy_num'] = $num;
                //商铺id
                $seller_id = $goods_data->goods->seller_id;

                //不同商铺分组拆单
                $goods_info[$seller_id][] = $goods_data;

            }


            $order_array = [];


            $address_copy_id=0;
            //存地址副本
            if(request()->input('delivery_type')==1){

                $address_copy=AddressCopy::create(\App\Model\Address::where('id',request()->input('address_id'))->first()->toArray());

                $address_copy_id=$address_copy->id;
            }

            foreach ($goods_info as $key => $value) {


                //计算订单总价
                $total_money = $getOrderPrice->getTotalMoney($value, 'price', 'buy_num');



                //生成订单
                $order_info = \App\Model\Order::create([
                    'order_no' => $this->create_order_no($user_id),
                    'user_id' => $user_id,
                    'seller_id' => $key,
                    'delivery_type' => request()->input('delivery_type'),
                    'note' => request()->input('note', ''),
                    'total_money' => $total_money,
                    'real_money' => $total_money,
                    'freight' => 0,
                    'status' => 1,
                    'address_id' => request()->input('address_id'),
                    'address_copy_id'=>$address_copy_id,
                    'expired_time'=>now()->addMinutes(\App\Tool\Order::getWaitTime())

                ]);


                //自提时
                if(request()->input('delivery_type')==2){

                    $store=request()->input('store');

                    //存自提信息
                    StoreCopy::create([
                        'name'=>$store['name'],
                        'province'=>$store['province'],
                        'city'=>$store['city'],
                        'area'=>$store['area'],
                        'phone'=>$store['phone'],
                        'detail'=>$store['detail'],
                        'order_id'=>$order_info->id
                    ]);

//                    //生成取货码
//                    ReceiptCode::createCode($order_info->id,$user_id);

                    $this->order_mention($order_info->id,
                        request()->input('mention_start_time'),
                        request()->input('mention_end_time')
                    );


                }

                $order_array[] = $order_info->toArray();

                foreach ($value as $k => $v) {

                    $price=$getOrderPrice->getRealPrice($v);

                    $snapped_sku_id=0;


                    if($v['snapped_price']) $snapped_sku_id=$v['snapped_sku']['id'];

                    //存储订单商品
                    OrderGoods::create([
                        'order_id' => $order_info->id,
                        'goods_id' => $v['goods_id'],
                        'goods_sku_id' => $v['id'],
                        'seller_id' => $key,
                        'goods_name' => $v['goods']['name'],
                        'num' => $v['buy_num'],
                        'sku_msg' => join(',', array_column($v['goods_sku_detail']->toArray(), 'value')),
                        'price' => $price,
                        'snapped_sku_id'=>$snapped_sku_id


                    ]);


                }


            }

            \DB::commit();

            //支付超时自动取消（消息队列）
            foreach ($order_array as $value){

                dispatch(new OrderCancel($user_id,$value['id']))
                    ->delay(now()->addMinutes(\App\Tool\Order::getWaitTime()));

            }



            return Json::code(1, 'success', join('*', array_column($order_array, 'id')));

        } catch (\Exception $exception) {

            \DB::rollBack();

            //回滚秒杀库存
            foreach ($this->stock as $v){

                Redis::incrby('snapped:num_goods_sku_id_'.$v['goods_sku_id'],$v['num']);

            }

            return Json::code(2,$exception->getMessage(),$exception->getLine());

        }
    }

    /**
     * 生成提货时间
     * Create by PeterYang
     * 2020/07/04 09:59:43
     * Email:904801074@qq.com
     * @param $order_id
     * @param $start_time
     * @param $end_time
     */
    private function order_mention($order_id,$start_time,$end_time){


        OrderMention::create([
            'order_id'=>$order_id,
            'start_time'=>Carbon::parse(str_replace('.','-',$start_time))->toDateTime(),
            'end_time'=>Carbon::parse(str_replace('.','-',$end_time))->toDateTime(),

        ]);


    }


    /**
     * 减库存
     * Create by Peter
     * 2020/01/07 15:51:02
     * Email:904801074@qq.com
     * @param $sku_id
     * @param $num
     * @param $goods_data
     * @throws \Exception
     *
     */
    function changeGoodsNum($sku_id, $num,$goods_data)
    {

//        exit(Json::code(2,Redis::get('snapped:num_goods_sku_id_'.$goods_data->snapped_sku->sku_id),$goods_data));

        //秒杀商品
        if($goods_data->snapped_price){

            $stock=Redis::get('snapped:num_goods_sku_id_'.$goods_data->snapped_sku->sku_id);

            if($stock<=0) throw new \Exception('商品库存不足！');

            //直接扣库存
            $value=Redis::decrby('snapped:num_goods_sku_id_'.$goods_data->snapped_sku->sku_id,$num);

            //存入已扣除的库存
            $this->stock[]=['goods_sku_id'=>$sku_id,'num'=>$num];

            if($value < 0) throw new \Exception('商品库存不足!');



        }else{
            //非秒杀

            $num_now = $goods_data['num'];

            if ($num_now <= 0) throw new \Exception('商品库存不足！');

            if($num_now-$num<0) throw new \Exception('商品库存不足！');

            GoodsSku::where('id', $sku_id)->decrement('num', $num);
        }




    }

    /**
     * 删除购物车商品
     * Create by Peter
     * 2020/01/07 15:50:47
     * Email:904801074@qq.com
     * @param $sku_id
     */
    function changeShopCarNum($sku_id)
    {

        $user_id = resolve('weapp_user')['id'];

        \App\Model\ShopCar::where('goods_sku_id', $sku_id)->where('user_id', $user_id)->delete();

    }

    /**
     * 生成订单号
     * Create by Peter
     * 2019/12/17 17:01:46
     * Email:904801074@qq.com
     * @param $user_id
     * @return string
     * @throws \Exception
     */
    function create_order_no($user_id)
    {

//        $number=Uuid::uuid1();


        return (string)(microtime(true) * 10000) . rand(1000, 9999) . $user_id;

    }

    /**
     * 支付页面获取信息
     * Create by Peter
     * 2019/12/20 13:15:56
     * Email:904801074@qq.com
     * @return false|string
     */
    function getOrderDetail()
    {

        try {
            $user_id = resolve('weapp_user')['id'];

            //可能是多个订单，8*9
            $order_id = request()->input('id');

            $order_array = explode('*', $order_id);

            $total = 0;
            foreach ($order_array as $key => $value) {

                $info = \App\Model\Order::findOrFail($value);

                $status = $info->status;

                PayStatus::throwError($status);

                if ($info->user_id != $user_id) throw new \Exception('这不是您的订单！');

                $real_money = $info->real_money;

                $total += $real_money;

            }

            return Json::code(1, 'success', ['total' => $total]);

        } catch (\Exception $exception) {


            return Json::code(2, $exception->getMessage());

        }


    }

    /**
     * 我的订单列表
     *
     * status:  1.待付款
     *          2.待取货
     *          3.已完成
     *          4.所有订单
     *          5.已取消
     * Create by PeterYang
     * 2020/07/04 14:31:31
     * Email:904801074@qq.com
     * @return array
     */
    function my_order()
    {



        $num = 6;

        $user_id = resolve('weapp_user')['id'];

        $list = \App\Model\Order::where('user_id', $user_id)->with(['order_goods.goods_sku' => function ($query) {

            //包括软删除的数据
            $query->withTrashed();
        }])
            ->orderBy('id', 'desc');


        $status = request()->input('status', -1);

//        if ($status != -1) $list->where('status', $status);

        switch ($status){

            //待付款
            case 1:

                $list->where('status',1)->where('expired_time','>',now());

                break;
            //待取货
            case 2:

                $list->where('status',11);
                break;

            //已完成
            case 3:

                $list->where('status',30);

                break;

            case 4:


               break;

            case 5:

                $list->where('status',22);

                break;


        }


        $list = paginate($list, request()->input('p', 1), $num);


        return $list;
    }

    /**
     * 订单取消
     * Create by Peter
     * 2019/12/24 10:58:21
     * Email:904801074@qq.com
     * @param \App\Model\Order $order
     * @return false|string
     * @throws \Exception
     */
    function order_cancel(\App\Model\Order $order)
    {

        try {

            $user_id = resolve('weapp_user')['id'];

            $id = request()->input('id');

            $order->order_cancel($user_id,$id);



            return Json::code(1, 'success');

        } catch (\Exception $exception) {


//
            return Json::code(2, '网络错误，请重试');

        }
    }


}
